/*=============================================================================
Copyright (c) 2005 AUTOMATED LOGIC CORPORATION

This file is part of DominoTomcatSSOIntegration.
http://www.automatedlogic.com/domblog.nsf/dx/DominoTomcatSSOIntegration

DominoTomcatSSOIntegration is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

DominoTomcatSSOIntegration is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
http://www.gnu.org/licenses/gpl.html
=============================================================================*/

package com.automatedlogic.domino.sso;

import lotus.domino.NotesException;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;

/**
 * After a user is authenticated, this object is stored in the user's session.  You may reference it in JSPs and Servlets.
 * It contains information about the person such as their hierarchal name, common name, Domino groups,
 * and the Person document from the Domino Directory.
 *
 * @author Brian Green, Automated Logic Corporation
 * @version 2.4.3, Feb 25 2005
 * @since JDK1.4.2_06
 */
public class DominoUserProfile implements DominoDirectoryConstants {

    /**
     * Person's hierarchal name.
     */
    private String personFullName;

    /**
     * Person's common name component of the hierarchal name.
     */
    private String personCommonName;

    /**
     * Domino Directory Groups where this person is a member.  It contains elements of type lotus.domino.Name
     */
    private Vector personGroupNames;

    /**
     * Domino Directory Groups where this person is a member.  It contains elements of type String.
     */
    private List personGroupList;

    /**
     * File Path Location of the Domino Directory that contains this Person document.
     */
    private String dominoDirectoryFilePath;

    /**
     * Domino Server Name of the Domino Directory that contains this Person document.
     */
    private String dominoDirectoryServer;


    /**
     * Person's name as a "Name" object.  Allows for more flexibility when writing applications.
     */
    private lotus.domino.Name personDominoName;

    /**
     * Person document located in the Domino Directory.  Remember that some properties and methods of the Person
     * object are only available when there is an active Domino session.
     */
    private lotus.domino.Document personDominoDirectoryPersonDocument;

    private String password;
    
    private String dominoUrl;
    
    
    /**
     * @return The person's hierarchal name.  For example, Samurai Jack/OU=Cartoons/O=ACME
     */
    public String getFullName() {
        return personFullName;
    }

    /**
     * @return The person's common name.  For example, Samurai Jack.
     */
    public String getCommonName() {
        return personCommonName;
    }

    /**
     * @return A listing of Domino Directory Groups where this person is a member.  It contains elements of type lotus.domino.Name
     */
    public Vector getPersonGroupNames() {
        return personGroupNames;
    }

    /**
     * @return A listing of Domino Directory Groups where this person is a member.  It contains elements of type String
     */
    public List getPersonGroupList() {
        return personGroupList;
    }


    /**
     * @return The Person document is stored in the Domino Directory.  This is the file path for that Domino Directory.
     */
    public String getDominoDirectoryFilePath() {
        return dominoDirectoryFilePath;
    }

    /**
     * @return The Person document is stored in the Domino Directory.  This is the name of the server for that Domino Directory.
     */
    public String getDominoDirectoryServer() {
        return dominoDirectoryServer;
    }


    /**
     * @return The person's name information as a Domino "Name" object.
     */
    public lotus.domino.Name getDominoName() {
        return personDominoName;
    }

    /**
     * If you need to know what Domino Directory the document is stored in,
     * then use getDominoDirectoryPersonDocument.getParentDatabase() to return a Database object.
     *
     * @return The Person document in the Domino Directory.
     */
    public lotus.domino.Document getDominoDirectoryPersonDocument() {
        return personDominoDirectoryPersonDocument;
    }


    /**
     * Collects information about the user.
     */
    public void refresh(HttpServletRequest http, String dominoServer) {

        //Open a session with the Domino server.  The Domino server must be running the HTTP and DIIOP tasks, and must accept connections for the user.
        DominoBridge dominoBridge = new DominoBridge();
        dominoBridge.openDominoSession(http, dominoServer);

        //Collect information about the user, if a session was opened with the Domino server.
        if (dominoBridge.isDominoSessionAvailable()) {

            //Get the current user's names.
            collectPersonNames(dominoBridge);

            //Get the current user's Person Document in the Domino Directory.  The user must have access to Read their own Person document from the directory.
            personDominoDirectoryPersonDocument = getPersonDocument(dominoBridge);
   
            collectDominoDirectoryInformation();

            //Close the session with the Domino server.
            dominoBridge.closeDominoSession();
        }
    }

    private void collectDominoDirectoryInformation() {

        if (personDominoDirectoryPersonDocument != null) {
            try {
                dominoDirectoryFilePath = personDominoDirectoryPersonDocument.getParentDatabase().getFilePath();
                dominoDirectoryServer = personDominoDirectoryPersonDocument.getParentDatabase().getServer();
            } catch (NotesException e) {
            }
        }

    }


    /**
     * Store the user's common and hierarchical names.
     *
     * @param dominoBridge
     */
    private void collectPersonNames(DominoBridge dominoBridge) {

        try {

            //Get the user's authenticated names.
            personDominoName = dominoBridge.dominoSession.getUserNameObject();
            personFullName = personDominoName.getCanonical();
            personCommonName = personDominoName.getCommon();

            //Group names may only be retrieved when the user's name is hierarchical.  (As of Domino 6.5.3)
            if (personDominoName.isHierarchical()) {
                try {
                    personGroupNames = dominoBridge.dominoSession.getUserGroupNameList();
                    setPersonGroupList();
                } catch (NullPointerException e) {
                }
            }

        } catch (NotesException e) {
            System.out.println("NotesException - " + e.id + " " + e.text);
        }

    }


    /**
     * Open the Domino server's Directory Assistance listing, look at each Domino Directory, and find the user's Person document.
     *
     * @param dominoBridge An active session must be available to the Domino server.
     * @return Document from a Domino Directory database.
     */
    private lotus.domino.Document getPersonDocument(DominoBridge dominoBridge) {

        try {

            //Look at each directory until we find the user's Person document.
            lotus.domino.Database dominoDirectoryDatabase;
            Vector books = dominoBridge.dominoSession.getAddressBooks();
            Enumeration b = books.elements();

            while (b.hasMoreElements()) {
                dominoDirectoryDatabase = (lotus.domino.Database) b.nextElement();

                try {
                    //The database can be opened if the user has access to it.
                    if (dominoDirectoryDatabase.open()) {

                        //Open a view in the Domino database.
                        lotus.domino.View dominoDirectoryView = dominoDirectoryDatabase.getView(dominoDirectoryViewName);
                        if (dominoDirectoryView != null) {
                            //Find the Person document.
                            lotus.domino.Document personDocument = dominoDirectoryView.getDocumentByKey(dominoBridge.dominoSession.getUserName(), true);
                            //Ignore any Person document that has been deleted.
                            if (personDocument != null) {
                                if (personDocument.isValid()) {
                                    if (!personDocument.isDeleted()) {
                                        return personDocument;
                                    }
                                }
                            }
                        }

                    }

                } catch (NotesException e) {
                }

            }
        } catch (NotesException e) {
            System.out.println("NotesException - " + e.id + " " + e.text);
            e.printStackTrace(System.out);
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }

        return null;
    }


    /**
     * Quick check to see if information was found on this person.
     *
     * @return True if information is known about the person, otherwise False.
     */
    public boolean isValid() {

        if (personFullName == null) {
            return false;
        }
        if (personFullName.equals("")) {
            return false;
        }
        return true;

    }


    /**
     * Determine if the user belongs to the specificied group.
     *
     * @param groupName The name of the group to check.  It is case-sensitive.
     * @return True if the person is a member of the group.
     */
    public boolean isMemberOfGroup(String groupName) {

        if (personGroupList == null) {
            return false;
        }

        if (personGroupList.contains(groupName)) {
            return true;
        } else {
            return false;
        }

    }


    /**
     * Stores the contents of personGroupNames (lotus.domino.Name) to personGroupList (String).
     */
    private void setPersonGroupList() {

        personGroupList = new ArrayList();

        if (personGroupNames == null) {
            return;
        }

        try {
            Enumeration g = personGroupNames.elements();
            while (g.hasMoreElements()) {
                lotus.domino.Name name = (lotus.domino.Name) g.nextElement();
                if (name != null) {
                    personGroupList.add(name.toString());
                }
            }

        } catch (Exception e) {
            e.printStackTrace(System.out);
        }

    }


    /**
     * @return An HTML string of all the groups names for this person.  Useful when debugging.
     */
    public String printPersonGroups() {

        if (personGroupNames == null) {
            return "";
        }

        String result = "";
        try {
            Enumeration g = personGroupNames.elements();
            while (g.hasMoreElements()) {
                lotus.domino.Name name = (lotus.domino.Name) g.nextElement();
                if (name != null) {
                    result += name.getAbbreviated() + "<br/>";
                }
            }

        } catch (NotesException e) {
            System.out.println("NotesException - " + e.id + " " + e.text);
            e.printStackTrace(System.out);
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
        return result;
    }


    /**
     * Given the name of an Item on the Person document, this will return the value(s) as a String.
     * It can only return the value of Items that are of datatype "Text".
     *
     * @param name The name of an Item on the Person document.
     * @return The value of the Item.
     */
    public String getPersonInfo(String name) {

        if (personDominoDirectoryPersonDocument == null) {
            return "";
        }

        try {
            lotus.domino.Item item = personDominoDirectoryPersonDocument.getFirstItem(name);
            if (item != null) {
                String v = item.getValueString();
                if (v != null) {
                    return v;
                }
            }
        } catch (NotesException e) {
        } catch (Exception e) {
        }
        return "";
    }


	/**
	 * @return Returns the password.
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @return Returns the dominoUrl.
	 */
	public String getDominoUrl() {
		return dominoUrl;
	}
	/**
	 * @param dominoUrl The dominoUrl to set.
	 */
	public void setDominoUrl(String dominoUrl) {
		this.dominoUrl = dominoUrl;
	}
	/**
	 * @param password The password to set.
	 */
	public void setPassword(String password) {
		this.password = password;
	}
}
